// src/utils/pdfGenerator.js
const puppeteer = require('puppeteer');
const path = require('path');
const fs = require('fs');

class PDFGenerator {
  constructor() {
    this.browser = null;
    // 设置 Chromium 路径
    this.executablePath = this.getChromiumPath();
  }

  // 获取 Chromium 路径
  getChromiumPath() {
    // 尝试多个可能的路径
    const possiblePaths = [
      '/usr/bin/chromium',
      '/usr/bin/chromium-browser',
      '/usr/bin/google-chrome',
      '/usr/bin/google-chrome-stable'
    ];

    for (const browserPath of possiblePaths) {
      try {
        if (fs.existsSync(browserPath)) {
          console.log('使用浏览器路径:', browserPath);
          return browserPath;
        }
      } catch (error) {
        console.warn('检查浏览器路径失败:', browserPath, error);
      }
    }

    console.warn('未找到系统浏览器，将尝试使用 puppeteer 自带的浏览器');
    return undefined;
  }

  async init() {
    if (!this.browser) {
      const launchOptions = {
        headless: true,
        args: [
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-dev-shm-usage',
          '--disable-gpu',
          '--disable-software-rasterizer',
          '--single-process',
          '--no-zygote'
        ]
      };

      // 如果找到了系统浏览器路径，就使用它
      if (this.executablePath) {
        launchOptions.executablePath = this.executablePath;
        console.log('使用已配置的浏览器路径:', this.executablePath);
      }

      try {
        this.browser = await puppeteer.launch(launchOptions);
        console.log('浏览器启动成功');
      } catch (error) {
        console.error('浏览器启动失败:', error);
        // 如果启动失败，尝试不使用指定路径
        if (launchOptions.executablePath) {
          console.log('尝试不使用指定路径启动浏览器');
          delete launchOptions.executablePath;
          this.browser = await puppeteer.launch(launchOptions);
        } else {
          throw error;
        }
      }
    }
  }

  // 兼容旧版本的等待方法
  async waitForTimeout(page, milliseconds) {
    if (page.waitForTimeout) {
      // 新版本的方法
      return page.waitForTimeout(milliseconds);
    } else {
      // 旧版本的方法
      return new Promise(resolve => setTimeout(resolve, milliseconds));
    }
  }

  async generatePDFFromURL(url, options = {}) {
    await this.init();
    const page = await this.browser.newPage();

    try {
      console.log(`正在访问URL: ${url}`);

      // 设置用户代理，避免被网站阻止
      await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');

      // 设置视图大小
      await page.setViewport({ width: 1280, height: 800 });

      await page.goto(url, {
        waitUntil: 'networkidle0',
        timeout: 30000
      });

      // 使用兼容的等待方法
      await this.waitForTimeout(page, 2000);

      const pdfBuffer = await this.generatePDFFromPage(page, options);
      return pdfBuffer;
    } catch (error) {
      console.error('访问URL失败:', error);
      throw new Error(`无法访问URL: ${error.message}`);
    } finally {
      await page.close();
    }
  }

  async generatePDFFromPage(page, options = {}) {
    const defaultOptions = {
      format: 'A4',
      printBackground: true,
      margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
      displayHeaderFooter: false
    };

    const pdfOptions = { ...defaultOptions, ...options };
    return await page.pdf(pdfOptions);
  }

  async generatePDFFromHTML(html, options = {}) {
    await this.init();
    const page = await this.browser.newPage();

    try {
      await page.setContent(html, { waitUntil: 'networkidle0' });
      const pdfBuffer = await this.generatePDFFromPage(page, options);
      return pdfBuffer;
    } finally {
      await page.close();
    }
  }

  async generatePDFFromTemplate(templateName, data, options = {}) {
    try {
      const templatePath = path.join(__dirname, '../templates', `${templateName}.html`);
      let html = await fs.promises.readFile(templatePath, 'utf8');
      html = this.replaceTemplateVariables(html, data);
      return await this.generatePDFFromHTML(html, options);
    } catch (error) {
      throw new Error(`模板处理失败: ${error.message}`);
    }
  }

  replaceTemplateVariables(html, data) {
    return html.replace(/\{\{(\w+)\}\}/g, (match, key) => {
      return data[key] || '';
    });
  }

  async close() {
    if (this.browser) {
      await this.browser.close();
      this.browser = null;
      console.log('浏览器已关闭');
    }
  }
}

module.exports = new PDFGenerator();